/**
    Copyright (c) 2009 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "BitonicSortMgr.h"

BitonicSortMgr::BitonicSortMgr()
{
    m_nSortMode = SORT_MODE_LOOP_MULT_STEP;
    //m_nSortMode = SORT_MODE_RECURSIVE;
    m_nSortDir = SORT_DIR_UP;
    m_pActiveBitonicSort = &m_bitonicSortDemo;
    m_nElemPerFrame = 30000;
    m_bResetData = false;
}

BitonicSortMgr::~BitonicSortMgr()
{
}

/**
    @param pd3dDevice    [in]            D3D Device
*/
void BitonicSortMgr::Create( ID3D11Device* pd3dDevice )
{
    // create data
    m_data.Create();

    // set data in each different bitonic sort implementation
    m_bitonicSortRecursiveCPU.Create( pd3dDevice, m_data.GetrData() );
    m_bitonicSortLoopCPU.Create( pd3dDevice, m_data.GetrData() );
    m_bitonicSortDemo.Create( pd3dDevice, m_data.GetrData() );    

    m_bitonicSortDemo.SortBegin( IsSortDirUp(), m_nElemPerFrame );
}

/**
    @param pd3dDevice                [in]            D3D Device
    @param pd3dImmediateContext        [in]            D3D Device Immediate Context
*/
void BitonicSortMgr::Update( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext )
{
    m_pActiveBitonicSort->Update();
    m_pActiveBitonicSort->UpdateBuffer( pd3dDevice, pd3dImmediateContext );    
}

/**
*/
void BitonicSortMgr::Destroy()
{
    m_bitonicSortLoopCPU.Destroy();
    m_bitonicSortRecursiveCPU.Destroy();
    m_bitonicSortDemo.Destroy();
}

/**    
    Begin sorting
*/
void BitonicSortMgr::BeginSort()
{
    // reset data
    if( m_bResetData ) {
        m_data.Create();
        m_pActiveBitonicSort->SetData( m_data.GetrData() );
    }

    if( m_nSortMode == SORT_MODE_RECURSIVE )
    {
        m_pActiveBitonicSort = &m_bitonicSortRecursiveCPU;
        // sort all at once
        m_pActiveBitonicSort->SetSortUp( IsSortDirUp() );
        m_pActiveBitonicSort->UpdateOnce();
    }
    else if( m_nSortMode == SORT_MODE_LOOP_ONE_STEP )
    {    
        m_pActiveBitonicSort = &m_bitonicSortLoopCPU;
        // sort all at once
        m_pActiveBitonicSort->SetSortUp( IsSortDirUp() );
        m_pActiveBitonicSort->UpdateOnce();
    }
    else if( m_nSortMode == SORT_MODE_LOOP_MULT_STEP )
    {    
        m_pActiveBitonicSort = &m_bitonicSortDemo;
        // sort in multiple frames
        BitonicSortDemo* pBitonicSortDemo = static_cast< BitonicSortDemo* >( m_pActiveBitonicSort );
        pBitonicSortDemo->SortBegin( IsSortDirUp(), m_nElemPerFrame );
    }
    else {
        assert( 0 );
    }
}

